
#include <asm.h>

.global C_SYMBOL(ARGB32Blit2ARGB32_Raw)
C_SYMBOL(ARGB32Blit2ARGB32_Raw):

R7= -0x24
R6= -0x20
height= -0x1C
SrcStep= -0x18
step= -0x14
srcPitch= -0x10

pSrc = 0x0;
srcX = 0x4;
srcY = 0x8;
argWidth = 0xC;
argHeight = 0x10;
argSrcPitch = 0x14;
srcOpacity = 0x18;

    MOV     R12, SP
    STMFD   SP!, {R4-R12,LR}
    SUB     SP, SP, #0x4C
    MUL     R4, R3, R2
    ADD     R1, R4, R1, LSL#2
    ADD     R2, R0, R1
    LDR     R4, [R12,#argSrcPitch]
    LDR     R5, [R12,#srcY]
    LDR     R6, [R12,#srcX]
    LDR     R8, [R12,#pSrc]
    MUL     R7, R4, R5
    ADD     R6, R7, R6, LSL#2
    ADD     R0, R8, R6
    MOV     R1, R4

    LDR     R4, [R12,#argWidth]
    LDR     R5, [R12,#argHeight]
    LDR     R8, [R12,#srcOpacity]

//  R0=pSrc,R1=srcPitch,R2=pDst,R3=dstPitch,R4=w,R5=h,R8=op

    MOV     R12, R5
    STR     R12, [SP,#0x4C+height]

    AND     R8, R8, #0xFF
    CMP     R8, #255
    BLT     _Start_T_

    MOV R4, R4, LSL #2
    STR R4, [SP,#0x4C+srcPitch]

    MOV R12, R8

    LDR R11, =0x00FF00FF
//    ORR R12, R12, R12, LSL #16

    MOV LR, R2
    SUB	R1, R1,	R4                          //R1 = SRC pitch - ROI width
    SUB	R3, R3,	R4                          //R3 = DST pitch - ROI width
    STR R3, [SP,#0x4C+step]
    STR R1, [SP,#0x4C+SrcStep]

//.long 0xe7fddefe
_Line_Start_:
    MOV	R6, R4                              //R6 = ROI width
    ADD	R7, LR,	#7                          //R2 = destination pointer
    BIC	R7, R7,	#7                          //Ceiling R7 ADDRESS to 8 byte aligned, suppose jumped N
    SUB	R7, R7,	LR                          //
    CMP	R7, #0                              //Compare to see if R7 is originally 8 byte aligned
    BEQ	_lc030_000669_                      //if so jump to _lc030_000669_

_Less_Than_32_:

    LDR   R3 ,[R0], #4
    LDR   R8 ,[LR]

    CMP	R7, R6                              //
    MOVGT	R7, R6                          //Let R7 be the min(N , width)
    SUB	R6, R6,	R7                          //Let R6 be width - N
    STR R6, [SP,#0x4C+R6]

_Process_Step_N_header_:


    SUBS  R7, R7, #4

    AND   R9, R11, R8               //R9:0G0B
    MOV   R5, R3, LSR #24
    RSB   R5, R5, #255
    MUL   R2, R9, R5
    AND   R10, R11, R8, LSR #8      //R10:0A0R
    LDRGT R8 ,[LR, #4]
    MUL   R6, R10, R5
    AND   R9, R2, R11, LSL #8
    AND   R10, R6, R11, LSL #8
    ORR   R10, R10, R9, LSR #8

    ADD   R10, R3, R10

    LDRGT   R3 ,[R0], #4
    STR   R10 ,[LR], #4

    BGT	_Process_Step_N_header_
    LDR R6, [SP,#0x4C+R6]
    CMP	R6, #0
    BEQ	_Next_Line_

_lc030_000669_:
    SUBS	R6, R6,	#0x10                   //R6 -= 32 byte
    ADDMI	R7, R6,	#0x10
    ADDMI	R6, R6,	#0x10
    BMI	    _Less_Than_32_                      //jumpt to _Less_Than_32_ if less than 32 byte

    LDR   R1 ,[R0], #4
    LDR   R8 ,[LR]
    STR   R7, [SP,#0x4C+R7]

_Loop_Aligned8_:

//    SUBS	R10, R6,	#0x40
//    LDRGT   R1, [R0, #0x3C]                     //Preload

    SUBS  R6, R6,	#0x10

    AND   R9, R11, R8               //R9:0G0B
    AND   R10, R11, R8, LSR #8      //R10:0A0R
    MOV   R3, R1, LSR #24
    RSB   R3, R3, #255
    MUL   R5, R9, R3
    LDR   R8 ,[LR, #4]
    MUL   R7, R10, R3
    AND   R9, R5, R11, LSL #8
    AND   R10, R7, R11, LSL #8
    ORR   R10, R10, R9, LSR #8
    ADD   R10, R1, R10
    LDR   R1 ,[R0], #4
    STR   R10 ,[LR], #4

    AND   R9, R11, R8               //R9:0G0B
    AND   R10, R11, R8, LSR #8      //R10:0A0R
    MOV   R3, R1, LSR #24
    RSB   R3, R3, #255
    MUL   R5, R9, R3
    LDR   R8 ,[LR, #4]
    MUL   R7, R10, R3
    AND   R9, R5, R11, LSL #8
    AND   R10, R7, R11, LSL #8
    ORR   R10, R10, R9, LSR #8
    ADD   R10, R1, R10
    LDR   R1 ,[R0], #4
    STR   R10 ,[LR], #4

    AND   R9, R11, R8               //R9:0G0B
    AND   R10, R11, R8, LSR #8      //R10:0A0R
    MOV   R3, R1, LSR #24
    RSB   R3, R3, #255
    MUL   R5, R9, R3
    LDR   R8 ,[LR, #4]
    MUL   R7, R10, R3
    AND   R9, R5, R11, LSL #8
    AND   R10, R7, R11, LSL #8
    ORR   R10, R10, R9, LSR #8
    ADD   R10, R1, R10
    LDR   R1 ,[R0], #4
    STR   R10 ,[LR], #4

    AND   R9, R11, R8               //R9:0G0B
    AND   R10, R11, R8, LSR #8      //R10:0A0R
    MOV   R3, R1, LSR #24
    RSB   R3, R3, #255
    MUL   R5, R9, R3
    LDRGE   R8 ,[LR, #4]
    MUL   R7, R10, R3
    AND   R9, R5, R11, LSL #8
    AND   R10, R7, R11, LSL #8
    ORR   R10, R10, R9, LSR #8
    ADD   R10, R1, R10
    LDRGE   R1 ,[R0], #4
    STR   R10 ,[LR], #4

    BGE	_Loop_Aligned8_

    LDR   R7, [SP,#0x4C+R7]
    ADDS	R6, R6,	#0x10
    BEQ	_Next_Line_
    MOVGT	R7, R6
    BGT	_Less_Than_32_

_Next_Line_:
    LDR R1, [SP,#0x4C+SrcStep]
    LDR R3, [SP,#0x4C+step]
    LDR R5, [SP,#0x4C+height]
    LDR R4, [SP,#0x4C+srcPitch]
    ADD	R0, R0,	R1
    ADD	LR, LR,	R3
    SUBS	R5, R5,	#1
    STR R5, [SP,#0x4C+height]

    BGT	_Line_Start_
    ADD     SP, SP, #0x4C
    LDMEQFD   SP, {R4-R11,SP,PC}



_Start_T_:

    CMP     R8, #0
    ADDEQ     SP, SP, #0x4C
    LDMEQFD   SP, {R4-R11,SP,PC}

    MOV R4, R4, LSL #2
    STR R4, [SP,#0x4C+srcPitch]

    MOV R12, R8

    LDR R11, =0x00FF00FF
//    ORR R12, R12, R12, LSL #16

    MOV LR, R2
    SUB	R1, R1,	R4                          //R1 = SRC pitch - ROI width
    SUB	R3, R3,	R4                          //R3 = DST pitch - ROI width
    STR R3, [SP,#0x4C+step]
    STR R1, [SP,#0x4C+SrcStep]

//.long 0xe7fddefe
_Line_Start_T_:
    MOV	R6, R4                              //R6 = ROI width
    ADD	R7, LR,	#7                          //R2 = destination pointer
    BIC	R7, R7,	#7                          //Ceiling R7 ADDRESS to 8 byte aligned, suppose jumped N
    SUB	R7, R7,	LR                          //
    CMP	R7, #0                              //Compare to see if R7 is originally 8 byte aligned
    BEQ	_lc030_000669_T_                      //if so jump to _lc030_000669_T_

_Less_Than_32_T_:

    LDR   R2 ,[R0], #4
    LDR   R8 ,[LR]

    CMP	R7, R6                              //
    MOVGT	R7, R6                          //Let R7 be the min(N , width)
    SUB	R6, R6,	R7                          //Let R6 be width - N
    STR R6, [SP,#0x4C+R6]

_Process_Step_N_header_T_:

    AND   R3, R11, R2               //R3:0G0B
    AND   R4, R11, R2, LSR #8       //R4:0A0R

    MUL   R2, R3, R12
    SUBS  R7, R7, #4
    MUL   R5, R4, R12
    MOV   R2, R2, LSR #8            //GB
    AND   R9, R11, R8               //R9:0G0B
    AND   R10, R11, R8, LSR #8      //R10:0A0R

    MOV   R5, R5, LSR #8            //AR
    AND   R3, R11, R2
    AND   R4, R11, R5
    MOV   R5, R4, LSR #16
    RSB   R5, R5, R11, LSR #16
    MUL   R2, R9, R5
    LDRGT   R8 ,[LR, #4]
    MUL   R6, R10, R5

    MOV   R9, R2, LSR #8            //GB
    MOV   R10, R6, LSR #8           //AR
    LDRGT   R2 ,[R0], #4
    AND   R9, R11, R9
    AND   R10, R11, R10
    ADD   R3, R3, R9
    ADD   R4, R4, R10
    ORR   R3, R3, R4, LSL #8

    STR   R3 ,[LR], #4

    BGT	_Process_Step_N_header_T_
    LDR R6, [SP,#0x4C+R6]
    CMP	R6, #0
    BEQ	_Next_Line_T_

_lc030_000669_T_:
    SUBS	R6, R6,	#0x10                   //R6 -= 32 byte
    ADDMI	R7, R6,	#0x10
    ADDMI	R6, R6,	#0x10
    BMI	    _Less_Than_32_T_                      //jumpt to _Less_Than_32_T_ if less than 32 byte

    LDR   R1 ,[R0], #4
    LDR   R8 ,[LR]
    STR   R7, [SP,#0x4C+R7]

_Loop_Aligned8_T_:

//    SUBS	R10, R6,	#0x40
//    LDRGT   R1, [R0, #0x3C]                     //Preload

    AND   R3, R11, R1               //R3:0G0B
    MUL   R2, R3, R12
    SUBS  R6, R6,	#0x10
    AND   R4, R11, R1, LSR #8       //R4:0A0R
    MUL   R5, R4, R12
    AND   R9, R11, R8               //R9:0G0B
    AND   R10, R11, R8, LSR #8      //R10:0A0R
    AND   R4, R5, R11, LSL #8
    MOV   R1, R1, LSR #24
    RSB   R1, R1, #255
    MUL   R5, R9, R1
    AND   R3, R2, R11, LSL #8
    LDR   R8 ,[LR, #4]
    MUL   R7, R10, R1
    AND   R9, R5, R11, LSL #8
    LDR   R1 ,[R0], #4
    AND   R10, R7, R11, LSL #8
    ADD   R3, R3, R9
    ADD   R4, R4, R10
    ORR   R3, R4, R3, LSR #8
    STR   R3 ,[LR], #4

    AND   R3, R11, R1               //R3:0G0B
    MUL   R2, R3, R12
    AND   R4, R11, R1, LSR #8       //R4:0A0R
    MUL   R5, R4, R12
    AND   R9, R11, R8               //R9:0G0B
    AND   R10, R11, R8, LSR #8      //R10:0A0R
    AND   R4, R5, R11, LSL #8
    MOV   R1, R1, LSR #24
    RSB   R1, R1, #255
    MUL   R5, R9, R1
    AND   R3, R2, R11, LSL #8
    LDR   R8 ,[LR, #4]
    MUL   R7, R10, R1
    AND   R9, R5, R11, LSL #8
    LDR   R1 ,[R0], #4
    AND   R10, R7, R11, LSL #8
    ADD   R3, R3, R9
    ADD   R4, R4, R10
    ORR   R3, R4, R3, LSR #8
    STR   R3 ,[LR], #4

    AND   R3, R11, R1               //R3:0G0B
    MUL   R2, R3, R12
    AND   R4, R11, R1, LSR #8       //R4:0A0R
    MUL   R5, R4, R12
    AND   R9, R11, R8               //R9:0G0B
    AND   R10, R11, R8, LSR #8      //R10:0A0R
    AND   R4, R5, R11, LSL #8
    MOV   R1, R1, LSR #24
    RSB   R1, R1, #255
    MUL   R5, R9, R1
    AND   R3, R2, R11, LSL #8
    LDR   R8 ,[LR, #4]
    MUL   R7, R10, R1
    AND   R9, R5, R11, LSL #8
    LDR   R1 ,[R0], #4
    AND   R10, R7, R11, LSL #8
    ADD   R3, R3, R9
    ADD   R4, R4, R10
    ORR   R3, R4, R3, LSR #8
    STR   R3 ,[LR], #4

    AND   R3, R11, R1               //R3:0G0B
    MUL   R2, R3, R12
    AND   R4, R11, R1, LSR #8       //R4:0A0R
    MUL   R5, R4, R12
    AND   R9, R11, R8               //R9:0G0B
    AND   R10, R11, R8, LSR #8      //R10:0A0R
    AND   R4, R5, R11, LSL #8
    MOV   R1, R1, LSR #24
    RSB   R1, R1, #255
    MUL   R5, R9, R1
    AND   R3, R2, R11, LSL #8
    LDRGE   R8 ,[LR, #4]
    MUL   R7, R10, R1
    AND   R9, R5, R11, LSL #8
    LDRGE   R1 ,[R0], #4
    AND   R10, R7, R11, LSL #8
    ADD   R3, R3, R9
    ADD   R4, R4, R10
    ORR   R3, R4, R3, LSR #8
    STR   R3 ,[LR], #4

    BGE	_Loop_Aligned8_T_

    LDR   R7, [SP,#0x4C+R7]
    ADDS	R6, R6,	#0x10
    BEQ	_Next_Line_T_
    MOVGT	R7, R6
    BGT	_Less_Than_32_T_

_Next_Line_T_:
    LDR R1, [SP,#0x4C+SrcStep]
    LDR R3, [SP,#0x4C+step]
    LDR R5, [SP,#0x4C+height]
    LDR R4, [SP,#0x4C+srcPitch]
    ADD	R0, R0,	R1
    ADD	LR, LR,	R3
    SUBS	R5, R5,	#1
    STR R5, [SP,#0x4C+height]

    BGT	_Line_Start_T_
    ADD     SP, SP, #0x4C
    LDMEQFD   SP, {R4-R11,SP,PC}
